﻿using FastMvc.Crud;
using FastMvc.Exceptions;
using FastMvc.Repositories;
using JQ.SAAS.DTO.OrgUser;
using JQ.SAAS.Entity;
using JQ.SAAS.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JQ.SAAS.Service
{
    class OrgUserService : CrudService<sys_user, OrgUserDto, string, OrgUserListRequestDto, OrgUserCreateDto, OrgUserUpdateDto>, IOrgUserService
    {
        private IRepository<org_user_role> _userRoleRepository;
        private IRepository<org_role> _roleRepository;
        public OrgUserService(
            IRepository<sys_user> userRepository,
            IRepository<org_role> roleRepository,
            IRepository<org_user_role> userRoleRepository)
            : base(userRepository)
        {
            _roleRepository = roleRepository;
            _userRoleRepository = userRoleRepository;
        }

        public async Task<List<OrgUserRoleSetDto>> GetRoles(string sId)
        {
            var user = await Repository.GetAsync(sId);
            if (user == null)
                throw new ApiException("未知的用户Id！");

            var roles = await _userRoleRepository.GetAllAsync(t =>t.sUserId == sId);

            return roles.Select(t => new OrgUserRoleSetDto { sRoleId = t.sId, sRoleName = t.sRoleName }).ToList();
        }

        public async Task<OrgUserResetPwdDto> ResetPassWord(OrgUserResetPwdDto resetDto)
        {
            var user = await Repository.GetAsync(resetDto.sId);
            if (user == null)
                throw new ApiException("未知的用户Id！");

            if (string.IsNullOrEmpty(resetDto.PassWord))
            {
                user.Password = RandomPwd();
            }
            else
            {
                user.Password = resetDto.PassWord;
            }

            await Repository.UpdateAsync(user);

            resetDto.PassWord = user.Password;
            return resetDto;
        }

        private string RandomPwd()
        {
            string pwd = "1qaz2wsx3edc4rfvbgt56yhnmju78ik,.lo90p;/!@#$%^&*()POIUYTREWQASDFGHJKLMNBVCXZ";
            Random rand = new Random(Guid.NewGuid().GetHashCode());
            string rp = "";
            for (int i = 0; i < 8; i++)
            {
                rp += pwd[rand.Next(0, pwd.Length)];
            }
            return rp;
        }

        public async Task SetLockState(OrgUserLockDto lockDto)
        {
            var user = await Repository.GetAsync(lockDto.sId);
            if (user == null)
                throw new ApiException("未知的用户Id！");

            user.iLocked = lockDto.iLock;
            await Repository.UpdateAsync(user);
        }

        public async Task SetRoles(string sId, List<OrgUserRoleSetDto> roles)
        {
            var user = await Repository.GetAsync(sId);
            if (user == null)
                throw new ApiException("未知的用户Id！");

            var roleids = roles.Select(t => t.sRoleId).ToList();
            var roleList = _roleRepository.GetAll(t => roleids.Contains(t.sId));
            roleids = roleList.Select(t => t.sId).ToList();

            var oldList = _userRoleRepository.GetAll(t => t.sUserId == sId);

            // 删除的
            var delIds = oldList.Where(t => !roleids.Contains(t.sRoleId)).Select(t => sId).ToList();

            // 新增的
            var oldRoleIds = oldList.Select(t => t.sRoleId).ToList();
            var newRoles = roleList.Where(t => !oldRoleIds.Contains(t.sId));

            await _userRoleRepository.RunTransAsync(rep => 
            {
                foreach (var did in delIds)
                {
                    rep.Delete(did);
                }

                foreach (var nrole in newRoles)
                {
                    org_user_role uRole = new org_user_role()
                    {
                        sId = Guid.NewGuid().ToString(),
                        sOrgId = user.sOrgId,
                        sOrgName = user.sOrgName,
                        sRoleId = nrole.sId,
                        sRoleName = nrole.sName,
                        sUserId = user.sId,
                        sUserNickName = user.NickName,
                        dCreateTime = DateTime.Now,
                        iDelete = 0
                    };

                    rep.Insert(uRole);
                }
            });
        }
    }
}
